home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / modulefinder.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2005-10-18  |  16.3 KB  |  658 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.4)
  3.  
  4. '''Find modules used by a script, using introspection.'''
  5. import dis
  6. import imp
  7. import marshal
  8. import os
  9. import sys
  10. import new
  11. if hasattr(sys.__stdout__, 'newlines'):
  12.     READ_MODE = 'U'
  13. else:
  14.     READ_MODE = 'r'
  15. LOAD_CONST = dis.opname.index('LOAD_CONST')
  16. IMPORT_NAME = dis.opname.index('IMPORT_NAME')
  17. STORE_NAME = dis.opname.index('STORE_NAME')
  18. STORE_GLOBAL = dis.opname.index('STORE_GLOBAL')
  19. STORE_OPS = [
  20.     STORE_NAME,
  21.     STORE_GLOBAL]
  22. packagePathMap = { }
  23.  
  24. def AddPackagePath(packagename, path):
  25.     paths = packagePathMap.get(packagename, [])
  26.     paths.append(path)
  27.     packagePathMap[packagename] = paths
  28.  
  29. replacePackageMap = { }
  30.  
  31. def ReplacePackage(oldname, newname):
  32.     replacePackageMap[oldname] = newname
  33.  
  34.  
  35. class Module:
  36.     
  37.     def __init__(self, name, file = None, path = None):
  38.         self.__name__ = name
  39.         self.__file__ = file
  40.         self.__path__ = path
  41.         self.__code__ = None
  42.         self.globalnames = { }
  43.         self.starimports = { }
  44.  
  45.     
  46.     def __repr__(self):
  47.         s = 'Module(%r' % (self.__name__,)
  48.         if self.__file__ is not None:
  49.             s = s + ', %r' % (self.__file__,)
  50.         
  51.         if self.__path__ is not None:
  52.             s = s + ', %r' % (self.__path__,)
  53.         
  54.         s = s + ')'
  55.         return s
  56.  
  57.  
  58.  
  59. class ModuleFinder:
  60.     
  61.     def __init__(self, path = None, debug = 0, excludes = [], replace_paths = []):
  62.         if path is None:
  63.             path = sys.path
  64.         
  65.         self.path = path
  66.         self.modules = { }
  67.         self.badmodules = { }
  68.         self.debug = debug
  69.         self.indent = 0
  70.         self.excludes = excludes
  71.         self.replace_paths = replace_paths
  72.         self.processed_paths = []
  73.  
  74.     
  75.     def msg(self, level, str, *args):
  76.         if level <= self.debug:
  77.             for i in range(self.indent):
  78.                 print '   ',
  79.             
  80.             print str,
  81.             for arg in args:
  82.                 print repr(arg),
  83.             
  84.             print 
  85.         
  86.  
  87.     
  88.     def msgin(self, *args):
  89.         level = args[0]
  90.         if level <= self.debug:
  91.             self.indent = self.indent + 1
  92.             self.msg(*args)
  93.         
  94.  
  95.     
  96.     def msgout(self, *args):
  97.         level = args[0]
  98.         if level <= self.debug:
  99.             self.indent = self.indent - 1
  100.             self.msg(*args)
  101.         
  102.  
  103.     
  104.     def run_script(self, pathname):
  105.         self.msg(2, 'run_script', pathname)
  106.         fp = open(pathname, READ_MODE)
  107.         stuff = ('', 'r', imp.PY_SOURCE)
  108.         self.load_module('__main__', fp, pathname, stuff)
  109.  
  110.     
  111.     def load_file(self, pathname):
  112.         (dir, name) = os.path.split(pathname)
  113.         (name, ext) = os.path.splitext(name)
  114.         fp = open(pathname, READ_MODE)
  115.         stuff = (ext, 'r', imp.PY_SOURCE)
  116.         self.load_module(name, fp, pathname, stuff)
  117.  
  118.     
  119.     def import_hook(self, name, caller = None, fromlist = None):
  120.         self.msg(3, 'import_hook', name, caller, fromlist)
  121.         parent = self.determine_parent(caller)
  122.         (q, tail) = self.find_head_package(parent, name)
  123.         m = self.load_tail(q, tail)
  124.         if not fromlist:
  125.             return q
  126.         
  127.         if m.__path__:
  128.             self.ensure_fromlist(m, fromlist)
  129.         
  130.  
  131.     
  132.     def determine_parent(self, caller):
  133.         self.msgin(4, 'determine_parent', caller)
  134.         if not caller:
  135.             self.msgout(4, 'determine_parent -> None')
  136.             return None
  137.         
  138.         pname = caller.__name__
  139.         if caller.__path__:
  140.             parent = self.modules[pname]
  141.             self.msgout(4, 'determine_parent ->', parent)
  142.             return parent
  143.         
  144.         if '.' in pname:
  145.             i = pname.rfind('.')
  146.             pname = pname[:i]
  147.             parent = self.modules[pname]
  148.             self.msgout(4, 'determine_parent ->', parent)
  149.             return parent
  150.         
  151.         self.msgout(4, 'determine_parent -> None')
  152.  
  153.     
  154.     def find_head_package(self, parent, name):
  155.         self.msgin(4, 'find_head_package', parent, name)
  156.         if '.' in name:
  157.             i = name.find('.')
  158.             head = name[:i]
  159.             tail = name[i + 1:]
  160.         else:
  161.             head = name
  162.             tail = ''
  163.         if parent:
  164.             qname = '%s.%s' % (parent.__name__, head)
  165.         else:
  166.             qname = head
  167.         q = self.import_module(head, qname, parent)
  168.         if q:
  169.             self.msgout(4, 'find_head_package ->', (q, tail))
  170.             return (q, tail)
  171.         
  172.         if parent:
  173.             qname = head
  174.             parent = None
  175.             q = self.import_module(head, qname, parent)
  176.             if q:
  177.                 self.msgout(4, 'find_head_package ->', (q, tail))
  178.                 return (q, tail)
  179.             
  180.         
  181.         self.msgout(4, 'raise ImportError: No module named', qname)
  182.         raise ImportError, 'No module named ' + qname
  183.  
  184.     
  185.     def load_tail(self, q, tail):
  186.         self.msgin(4, 'load_tail', q, tail)
  187.         m = q
  188.         while tail:
  189.             i = tail.find('.')
  190.             if i < 0:
  191.                 i = len(tail)
  192.             
  193.             head = tail[:i]
  194.             tail = tail[i + 1:]
  195.             mname = '%s.%s' % (m.__name__, head)
  196.             m = self.import_module(head, mname, m)
  197.             if not m:
  198.                 self.msgout(4, 'raise ImportError: No module named', mname)
  199.                 raise ImportError, 'No module named ' + mname
  200.                 continue
  201.         self.msgout(4, 'load_tail ->', m)
  202.         return m
  203.  
  204.     
  205.     def ensure_fromlist(self, m, fromlist, recursive = 0):
  206.         self.msg(4, 'ensure_fromlist', m, fromlist, recursive)
  207.         for sub in fromlist:
  208.             if sub == '*':
  209.                 if not recursive:
  210.                     all = self.find_all_submodules(m)
  211.                     if all:
  212.                         self.ensure_fromlist(m, all, 1)
  213.                     
  214.                 
  215.             recursive
  216.             if not hasattr(m, sub):
  217.                 subname = '%s.%s' % (m.__name__, sub)
  218.                 submod = self.import_module(sub, subname, m)
  219.                 if not submod:
  220.                     raise ImportError, 'No module named ' + subname
  221.                 
  222.             submod
  223.         
  224.  
  225.     
  226.     def find_all_submodules(self, m):
  227.         if not m.__path__:
  228.             return None
  229.         
  230.         modules = { }
  231.         suffixes = []
  232.         for triple in imp.get_suffixes():
  233.             suffixes.append(triple[0])
  234.         
  235.         for dir in m.__path__:
  236.             
  237.             try:
  238.                 names = os.listdir(dir)
  239.             except os.error:
  240.                 self.msg(2, "can't list directory", dir)
  241.                 continue
  242.  
  243.             for name in names:
  244.                 mod = None
  245.                 for suff in suffixes:
  246.                     n = len(suff)
  247.                     if name[-n:] == suff:
  248.                         mod = name[:-n]
  249.                         break
  250.                         continue
  251.                 
  252.                 if mod and mod != '__init__':
  253.                     modules[mod] = mod
  254.                     continue
  255.             
  256.         
  257.         return modules.keys()
  258.  
  259.     
  260.     def import_module(self, partname, fqname, parent):
  261.         self.msgin(3, 'import_module', partname, fqname, parent)
  262.         
  263.         try:
  264.             m = self.modules[fqname]
  265.         except KeyError:
  266.             pass
  267.  
  268.         self.msgout(3, 'import_module ->', m)
  269.         return m
  270.         if self.badmodules.has_key(fqname):
  271.             self.msgout(3, 'import_module -> None')
  272.             return None
  273.         
  274.         if parent and parent.__path__ is None:
  275.             self.msgout(3, 'import_module -> None')
  276.             return None
  277.         
  278.         
  279.         try:
  280.             if parent:
  281.                 pass
  282.             (fp, pathname, stuff) = self.find_module(partname, parent.__path__, parent)
  283.         except ImportError:
  284.             self.msgout(3, 'import_module ->', None)
  285.             return None
  286.  
  287.         
  288.         try:
  289.             m = self.load_module(fqname, fp, pathname, stuff)
  290.         finally:
  291.             if fp:
  292.                 fp.close()
  293.             
  294.  
  295.         if parent:
  296.             setattr(parent, partname, m)
  297.         
  298.         self.msgout(3, 'import_module ->', m)
  299.         return m
  300.  
  301.     
  302.     def load_module(self, fqname, fp, pathname, .8):
  303.         (suffix, mode, type) = .8
  304.         if fp:
  305.             pass
  306.         self.msgin(2, 'load_module', fqname, 'fp', pathname)
  307.         if type == imp.PKG_DIRECTORY:
  308.             m = self.load_package(fqname, pathname)
  309.             self.msgout(2, 'load_module ->', m)
  310.             return m
  311.         
  312.         if type == imp.PY_SOURCE:
  313.             co = compile(fp.read() + '\n', pathname, 'exec')
  314.         elif type == imp.PY_COMPILED:
  315.             if fp.read(4) != imp.get_magic():
  316.                 self.msgout(2, 'raise ImportError: Bad magic number', pathname)
  317.                 raise ImportError, 'Bad magic number in %s' % pathname
  318.             
  319.             fp.read(4)
  320.             co = marshal.load(fp)
  321.         else:
  322.             co = None
  323.         m = self.add_module(fqname)
  324.         m.__file__ = pathname
  325.         if co:
  326.             if self.replace_paths:
  327.                 co = self.replace_paths_in_code(co)
  328.             
  329.             m.__code__ = co
  330.             self.scan_code(co, m)
  331.         
  332.         self.msgout(2, 'load_module ->', m)
  333.         return m
  334.  
  335.     
  336.     def _add_badmodule(self, name, caller):
  337.         if name not in self.badmodules:
  338.             self.badmodules[name] = { }
  339.         
  340.         self.badmodules[name][caller.__name__] = 1
  341.  
  342.     
  343.     def _safe_import_hook(self, name, caller, fromlist):
  344.         if name in self.badmodules:
  345.             self._add_badmodule(name, caller)
  346.             return None
  347.         
  348.         
  349.         try:
  350.             self.import_hook(name, caller)
  351.         except ImportError:
  352.             msg = None
  353.             self.msg(2, 'ImportError:', str(msg))
  354.             self._add_badmodule(name, caller)
  355.  
  356.         if fromlist:
  357.             for sub in fromlist:
  358.                 if sub in self.badmodules:
  359.                     self._add_badmodule(sub, caller)
  360.                     continue
  361.                 
  362.                 
  363.                 try:
  364.                     self.import_hook(name, caller, [
  365.                         sub])
  366.                 continue
  367.                 except ImportError:
  368.                     msg = None
  369.                     self.msg(2, 'ImportError:', str(msg))
  370.                     fullname = name + '.' + sub
  371.                     self._add_badmodule(fullname, caller)
  372.                     continue
  373.                 
  374.  
  375.             
  376.         
  377.  
  378.     
  379.     def scan_code(self, co, m):
  380.         code = co.co_code
  381.         n = len(code)
  382.         i = 0
  383.         fromlist = None
  384.         while i < n:
  385.             c = code[i]
  386.             i = i + 1
  387.             op = ord(c)
  388.             if op >= dis.HAVE_ARGUMENT:
  389.                 oparg = ord(code[i]) + ord(code[i + 1]) * 256
  390.                 i = i + 2
  391.             
  392.             if op == LOAD_CONST:
  393.                 fromlist = co.co_consts[oparg]
  394.                 continue
  395.             if op == IMPORT_NAME:
  396.                 name = co.co_names[oparg]
  397.                 have_star = 0
  398.                 self._safe_import_hook(name, m, fromlist)
  399.                 if have_star:
  400.                     mm = None
  401.                     if m.__path__:
  402.                         mm = self.modules.get(m.__name__ + '.' + name)
  403.                     
  404.                     if mm is None:
  405.                         mm = self.modules.get(name)
  406.                     
  407.                     if mm is not None:
  408.                         m.globalnames.update(mm.globalnames)
  409.                         m.starimports.update(mm.starimports)
  410.                         if mm.__code__ is None:
  411.                             m.starimports[name] = 1
  412.                         
  413.                     else:
  414.                         m.starimports[name] = 1
  415.                 
  416.             have_star
  417.             if op in STORE_OPS:
  418.                 name = co.co_names[oparg]
  419.                 m.globalnames[name] = 1
  420.                 continue
  421.             None if fromlist is not None else []
  422.         for c in co.co_consts:
  423.             if isinstance(c, type(co)):
  424.                 self.scan_code(c, m)
  425.                 continue
  426.         
  427.  
  428.     
  429.     def load_package(self, fqname, pathname):
  430.         self.msgin(2, 'load_package', fqname, pathname)
  431.         newname = replacePackageMap.get(fqname)
  432.         if newname:
  433.             fqname = newname
  434.         
  435.         m = self.add_module(fqname)
  436.         m.__file__ = pathname
  437.         m.__path__ = [
  438.             pathname]
  439.         m.__path__ = m.__path__ + packagePathMap.get(fqname, [])
  440.         (fp, buf, stuff) = self.find_module('__init__', m.__path__)
  441.         self.load_module(fqname, fp, buf, stuff)
  442.         self.msgout(2, 'load_package ->', m)
  443.         return m
  444.  
  445.     
  446.     def add_module(self, fqname):
  447.         if self.modules.has_key(fqname):
  448.             return self.modules[fqname]
  449.         
  450.         self.modules[fqname] = m = Module(fqname)
  451.         return m
  452.  
  453.     
  454.     def find_module(self, name, path, parent = None):
  455.         if parent is not None:
  456.             fullname = parent.__name__ + '.' + name
  457.         else:
  458.             fullname = name
  459.         if fullname in self.excludes:
  460.             self.msgout(3, 'find_module -> Excluded', fullname)
  461.             raise ImportError, name
  462.         
  463.         if path is None:
  464.             if name in sys.builtin_module_names:
  465.                 return (None, None, ('', '', imp.C_BUILTIN))
  466.             
  467.             path = self.path
  468.         
  469.         return imp.find_module(name, path)
  470.  
  471.     
  472.     def report(self):
  473.         '''Print a report to stdout, listing the found modules with their
  474.         paths, as well as modules that are missing, or seem to be missing.
  475.         '''
  476.         print 
  477.         print '  %-25s %s' % ('Name', 'File')
  478.         print '  %-25s %s' % ('----', '----')
  479.         keys = self.modules.keys()
  480.         keys.sort()
  481.         for key in keys:
  482.             m = self.modules[key]
  483.             if m.__path__:
  484.                 print 'P',
  485.             else:
  486.                 print 'm',
  487.             print '%-25s' % key,
  488.             if not m.__file__:
  489.                 pass
  490.             print ''
  491.         
  492.         (missing, maybe) = self.any_missing_maybe()
  493.         if missing:
  494.             print 
  495.             print 'Missing modules:'
  496.             for name in missing:
  497.                 mods = self.badmodules[name].keys()
  498.                 mods.sort()
  499.                 print '?', name, 'imported from', ', '.join(mods)
  500.             
  501.         
  502.         if maybe:
  503.             print 
  504.             print 'Submodules thay appear to be missing, but could also be', 'global names in the parent package:'
  505.             for name in maybe:
  506.                 mods = self.badmodules[name].keys()
  507.                 mods.sort()
  508.                 print '?', name, 'imported from', ', '.join(mods)
  509.             
  510.         
  511.  
  512.     
  513.     def any_missing(self):
  514.         '''Return a list of modules that appear to be missing. Use
  515.         any_missing_maybe() if you want to know which modules are
  516.         certain to be missing, and which *may* be missing.
  517.         '''
  518.         (missing, maybe) = self.any_missing_maybe()
  519.         return missing + maybe
  520.  
  521.     
  522.     def any_missing_maybe(self):
  523.         '''Return two lists, one with modules that are certainly missing
  524.         and one with modules that *may* be missing. The latter names could
  525.         either be submodules *or* just global names in the package.
  526.  
  527.         The reason it can\'t always be determined is that it\'s impossible to
  528.         tell which names are imported when "from module import *" is done
  529.         with an extension module, short of actually importing it.
  530.         '''
  531.         missing = []
  532.         maybe = []
  533.         for name in self.badmodules:
  534.             if name in self.excludes:
  535.                 continue
  536.             
  537.             i = name.rfind('.')
  538.             if i < 0:
  539.                 missing.append(name)
  540.                 continue
  541.             
  542.             subname = name[i + 1:]
  543.             pkgname = name[:i]
  544.             pkg = self.modules.get(pkgname)
  545.             if pkg is not None:
  546.                 if pkgname in self.badmodules[name]:
  547.                     missing.append(name)
  548.                 elif subname in pkg.globalnames:
  549.                     pass
  550.                 elif pkg.starimports:
  551.                     maybe.append(name)
  552.                 else:
  553.                     missing.append(name)
  554.             pkgname in self.badmodules[name]
  555.             missing.append(name)
  556.         
  557.         missing.sort()
  558.         maybe.sort()
  559.         return (missing, maybe)
  560.  
  561.     
  562.     def replace_paths_in_code(self, co):
  563.         new_filename = original_filename = os.path.normpath(co.co_filename)
  564.         for f, r in self.replace_paths:
  565.             if original_filename.startswith(f):
  566.                 new_filename = r + original_filename[len(f):]
  567.                 break
  568.                 continue
  569.         
  570.         if self.debug and original_filename not in self.processed_paths:
  571.             if new_filename != original_filename:
  572.                 self.msgout(2, 'co_filename %r changed to %r' % (original_filename, new_filename))
  573.             else:
  574.                 self.msgout(2, 'co_filename %r remains unchanged' % (original_filename,))
  575.             self.processed_paths.append(original_filename)
  576.         
  577.         consts = list(co.co_consts)
  578.         for i in range(len(consts)):
  579.             if isinstance(consts[i], type(co)):
  580.                 consts[i] = self.replace_paths_in_code(consts[i])
  581.                 continue
  582.         
  583.         return new.code(co.co_argcount, co.co_nlocals, co.co_stacksize, co.co_flags, co.co_code, tuple(consts), co.co_names, co.co_varnames, new_filename, co.co_name, co.co_firstlineno, co.co_lnotab, co.co_freevars, co.co_cellvars)
  584.  
  585.  
  586.  
  587. def test():
  588.     import getopt
  589.     
  590.     try:
  591.         (opts, args) = getopt.getopt(sys.argv[1:], 'dmp:qx:')
  592.     except getopt.error:
  593.         msg = None
  594.         print msg
  595.         return None
  596.  
  597.     debug = 1
  598.     domods = 0
  599.     addpath = []
  600.     exclude = []
  601.     for o, a in opts:
  602.         if o == '-d':
  603.             debug = debug + 1
  604.         
  605.         if o == '-m':
  606.             domods = 1
  607.         
  608.         if o == '-p':
  609.             addpath = addpath + a.split(os.pathsep)
  610.         
  611.         if o == '-q':
  612.             debug = 0
  613.         
  614.         if o == '-x':
  615.             exclude.append(a)
  616.             continue
  617.     
  618.     if not args:
  619.         script = 'hello.py'
  620.     else:
  621.         script = args[0]
  622.     path = sys.path[:]
  623.     path[0] = os.path.dirname(script)
  624.     path = addpath + path
  625.     if debug > 1:
  626.         print 'path:'
  627.         for item in path:
  628.             print '   ', repr(item)
  629.         
  630.     
  631.     mf = ModuleFinder(path, debug, exclude)
  632.     for arg in args[1:]:
  633.         if arg == '-m':
  634.             domods = 1
  635.             continue
  636.         
  637.         if domods:
  638.             if arg[-2:] == '.*':
  639.                 mf.import_hook(arg[:-2], None, [
  640.                     '*'])
  641.             else:
  642.                 mf.import_hook(arg)
  643.         arg[-2:] == '.*'
  644.         mf.load_file(arg)
  645.     
  646.     mf.run_script(script)
  647.     mf.report()
  648.     return mf
  649.  
  650. if __name__ == '__main__':
  651.     
  652.     try:
  653.         mf = test()
  654.     except KeyboardInterrupt:
  655.         print '\n[interrupt]'
  656.  
  657.  
  658.